home *** CD-ROM | disk | FTP | other *** search
/ Aminet 40 / Aminet 40 (2000)(Schatztruhe)[!][Dec 2000].iso / Aminet / dev / lang / Python16_Src.lha / Python16_Source / Modules / main.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-09-10  |  9.9 KB  |  439 lines

  1. /* Python interpreter main program */
  2.  
  3. #include "Python.h"
  4. #include "osdefs.h"
  5.  
  6. #ifdef HAVE_UNISTD_H
  7. #include <unistd.h>
  8. #endif
  9.  
  10. #ifdef MS_WINDOWS
  11. #include <fcntl.h>
  12. #endif
  13.  
  14. #if defined(PYOS_OS2) || defined(MS_WINDOWS)
  15. #define PYTHONHOMEHELP "<prefix>\\lib"
  16. #else
  17. #define PYTHONHOMEHELP "<prefix>/python1.6"
  18. #endif
  19.  
  20. /* Interface to getopt(): */
  21. extern int optind;
  22. extern char *optarg;
  23. extern int getopt(); /* PROTO((int, char **, char *)); -- not standardized */
  24.  
  25.  
  26. /* For Py_GetArgcArgv(); set by main() */
  27. static char **orig_argv;
  28. static int  orig_argc;
  29.  
  30. /* Short usage message (with %s for argv0) */
  31. static char *usage_line =
  32. "usage: %s [option] ... [-c cmd | file | -] [arg] ...\n";
  33.  
  34. /* Long usage message, split into parts < 512 bytes */
  35. static char *usage_top = "\
  36. Options and arguments (and corresponding environment variables):\n\
  37. -d     : debug output from parser (also PYTHONDEBUG=x)\n\
  38. -i     : inspect interactively after running script, (also PYTHONINSPECT=x)\n\
  39.          and force prompts, even if stdin does not appear to be a terminal\n\
  40. -O     : optimize generated bytecode (a tad; also PYTHONOPTIMIZE=x)\n\
  41. -OO    : remove doc-strings in addition to the -O optimizations\n\
  42. -S     : don't imply 'import site' on initialization\n\
  43. -t     : issue warnings about inconsistent tab usage (-tt: issue errors)\n\
  44. ";
  45. static char *usage_mid = "\
  46. -u     : unbuffered binary stdout and stderr (also PYTHONUNBUFFERED=x)\n\
  47. -U     : Unicode literals: treats '...' literals like u'...'\n\
  48. -v     : verbose (trace import statements) (also PYTHONVERBOSE=x)\n\
  49. -x     : skip first line of source, allowing use of non-Unix forms of #!cmd\n\
  50. -c cmd : program passed in as string (terminates option list)\n\
  51. file   : program read from script file\n\
  52. -      : program read from stdin (default; interactive mode if a tty)\n\
  53. ";
  54. static char *usage_bot = "\
  55. arg ...: arguments passed to program in sys.argv[1:]\n\
  56. Other environment variables:\n\
  57. PYTHONSTARTUP: file executed on interactive startup (no default)\n\
  58. PYTHONPATH   : '%c'-separated list of directories prefixed to the\n\
  59.                default module search path.  The result is sys.path.\n\
  60. PYTHONHOME   : alternate <prefix> directory (or <prefix>%c<exec_prefix>).\n\
  61.                The default module search path uses %s.\n\
  62. ";
  63.  
  64.  
  65. #ifdef __SASC
  66. extern char __stdiowin[] = "CON:0/12/640/200/Python";
  67. extern char __stdiov37[] = "/AUTO";
  68. #endif
  69.  
  70. #ifdef _AMIGA
  71. #include <proto/dos.h>
  72. #include <proto/exec.h>
  73. #endif /* AMIGA */
  74.  
  75. #ifdef INET225
  76. #include <proto/socket.h>
  77.  
  78. struct Library *SockBase = NULL;
  79.  
  80. int checksocketlib(void)
  81. {
  82.     if(!SockBase)
  83.     {
  84.         if(SockBase=OpenLibrary("inet:libs/socket.library",4))
  85.         {
  86.             setup_sockets(FD_SETSIZE, &errno);
  87.         }
  88.         else
  89.         {
  90.             PyErr_SetString(PyExc_SystemError, "Couldn't open inet:libs/socket.library V4+ (I-Net225 started?)");
  91.             return 0;
  92.         }
  93.     }
  94.     return 1;
  95. }
  96.  
  97. int checkusergrouplib(void)
  98. {
  99.     return checksocketlib();
  100. }
  101.  
  102. #endif /* INET225 */
  103.  
  104. #ifdef AMITCP
  105. #include <proto/socket.h>
  106. #include <amitcp/socketbasetags.h>
  107.  
  108. /* proto for special AmiTCP utility funcion; see _chkufb.c */
  109. extern long _install_AmiTCP_callback(void);
  110.  
  111.  
  112. /* global h_errno */
  113. int h_errno = 0;
  114.  
  115. struct Library *UserGroupBase = NULL;
  116. struct Library *SocketBase = NULL;
  117.  
  118. int checkusergrouplib(void)
  119. {
  120.     if(!UserGroupBase)
  121.     {
  122.         if(!(UserGroupBase=OpenLibrary("usergroup.library",4)))
  123.         {
  124.             PyErr_SetString(PyExc_SystemError, "Couldn't open usergroup.library");
  125.             return 0;
  126.         }
  127.     }
  128.     return 1;
  129. }
  130.  
  131. int checksocketlib(void)
  132. {
  133.     if(!SocketBase)
  134.     {
  135.         if(SocketBase=OpenLibrary("bsdsocket.library",4))
  136.         {
  137.             /*
  138.              * Succesfull. Now tell bsdsocket.library:
  139.              * - the address of our errno
  140.              * - the address of our h_errno
  141.              * - our program name
  142.              */
  143.             SocketBaseTags(SBTM_SETVAL(SBTC_ERRNOPTR(sizeof(errno))), &errno,
  144.                            SBTM_SETVAL(SBTC_HERRNOLONGPTR), &h_errno,
  145.                            SBTM_SETVAL(SBTC_LOGTAGPTR), "Python",
  146.                            TAG_END);
  147.         }
  148.         else
  149.         {
  150.             PyErr_SetString(PyExc_SystemError, "Couldn't open bsdsocket.library (start AmiTCP)");
  151.             return 0;
  152.         }
  153.     }
  154.     return 1;
  155. }
  156.  
  157. #endif
  158.  
  159. #ifdef _AMIGA
  160. BOOL from_WB = FALSE;    /* not static! getpath.c needs it! */
  161. static void AmigaCleanup(void)
  162. {
  163. #ifdef AMITCP
  164.     if(UserGroupBase)
  165.     {
  166.         CloseLibrary(UserGroupBase);
  167.         UserGroupBase=NULL;
  168.     }
  169.     if(SocketBase)
  170.     {
  171.         CloseLibrary(SocketBase);
  172.         SocketBase=NULL;
  173.     }
  174. #endif
  175. #ifdef INET225
  176.     if(SockBase)
  177.     {
  178.         cleanup_sockets();
  179.         CloseLibrary(SockBase);
  180.         SockBase = NULL;
  181.     }
  182. #endif
  183.     if(from_WB) Delay(112); // small exit delay before closing WB window
  184. }
  185. #endif
  186.  
  187.  
  188. /* Main program */
  189.  
  190. DL_EXPORT(int)
  191. Py_Main(argc, argv)
  192.     int argc;
  193.     char **argv;
  194. {
  195.     int c;
  196.     int sts;
  197.     char *command = NULL;
  198.     char *filename = NULL;
  199.     FILE *fp = stdin;
  200.     char *p;
  201.     int inspect = 0;
  202.     int unbuffered = 0;
  203.     int skipfirstline = 0;
  204.     int stdin_is_interactive = 0;
  205.  
  206. #ifdef _AMIGA
  207.     if(argc == 0)
  208.     {
  209.         /* Invoked from WorkBench... use WorkBench arguments  */
  210.         /* Make sure <dos.h> was included earlier in order to */
  211.         /* declare _WBArgc and _WBArgv.                       */
  212.         argc = _WBArgc;
  213.         argv = _WBArgv;
  214.         from_WB = TRUE;
  215.     }
  216.  
  217.     atexit(AmigaCleanup);   /* cleanup func */
  218. //  setbuf(stderr,NULL);    /* set error output UNBUFFERED */
  219.  
  220. #endif
  221.  
  222.     orig_argc = argc;    /* For Py_GetArgcArgv() */
  223.     orig_argv = argv;
  224.  
  225.     if ((p = getenv("PYTHONINSPECT")) && *p != '\0')
  226.         inspect = 1;
  227.     if ((p = getenv("PYTHONUNBUFFERED")) && *p != '\0')
  228.         unbuffered = 1;
  229.  
  230.     while ((c = getopt(argc, argv, "c:diOStuUvxX")) != EOF) {
  231.         if (c == 'c') {
  232.             /* -c is the last option; following arguments
  233.                that look like options are left for the
  234.                the command to interpret. */
  235.             command = malloc(strlen(optarg) + 2);
  236.             if (command == NULL)
  237.                 Py_FatalError(
  238.                    "not enough memory to copy -c argument");
  239.             strcpy(command, optarg);
  240.             strcat(command, "\n");
  241.             break;
  242.         }
  243.         
  244.         switch (c) {
  245.  
  246.         case 'd':
  247.             Py_DebugFlag++;
  248.             break;
  249.  
  250.         case 'i':
  251.             inspect++;
  252.             Py_InteractiveFlag++;
  253.             break;
  254.  
  255.         case 'O':
  256.             Py_OptimizeFlag++;
  257.             break;
  258.  
  259.         case 'S':
  260.             Py_NoSiteFlag++;
  261.             break;
  262.  
  263.         case 't':
  264.             Py_TabcheckFlag++;
  265.             break;
  266.  
  267.         case 'u':
  268.             unbuffered++;
  269.             break;
  270.  
  271.         case 'v':
  272.             Py_VerboseFlag++;
  273.             break;
  274.  
  275.         case 'x':
  276.             skipfirstline = 1;
  277.             break;
  278.  
  279.         case 'U':
  280.             Py_UnicodeFlag++;
  281.             break;
  282.  
  283.         /* This space reserved for other options */
  284.  
  285.         default:
  286.             fprintf(stderr, usage_line, argv[0]);
  287.             fprintf(stderr, usage_top);
  288.             fprintf(stderr, usage_mid);
  289.             fprintf(stderr, usage_bot,
  290.                 DELIM, DELIM, PYTHONHOMEHELP);
  291. #ifdef _AMIGA
  292.             fprintf(stderr,"Python and Python programs can also be started from the Workbench,\ntooltypes will be converted to command-line arguments.\n");
  293. #endif
  294.             exit(2);
  295.             /*NOTREACHED*/
  296.  
  297.         }
  298.     }
  299.  
  300.     if (command == NULL && optind < argc &&
  301.         strcmp(argv[optind], "-") != 0)
  302.     {
  303.         filename = argv[optind];
  304.         if (filename != NULL) {
  305.             if ((fp = fopen(filename, "r")) == NULL) {
  306.                 fprintf(stderr, "%s: can't open file '%s'\n",
  307.                     argv[0], filename);
  308.                 exit(2);
  309.             }
  310.             else if (skipfirstline) {
  311.                 int ch;
  312.                 /* Push back first newline so line numbers
  313.                    remain the same */
  314.                 while ((ch = getc(fp)) != EOF) {
  315.                     if (ch == '\n') {
  316.                         (void)ungetc(ch, fp);
  317.                         break;
  318.                     }
  319.                 }
  320.             }
  321.         }
  322.     }
  323.  
  324.     stdin_is_interactive = Py_FdIsInteractive(stdin, (char *)0);
  325.  
  326.     if (unbuffered) {
  327. #ifdef MS_WINDOWS
  328.         _setmode(fileno(stdin), O_BINARY);
  329.         _setmode(fileno(stdout), O_BINARY);
  330. #endif
  331. #ifndef MPW
  332. #ifdef HAVE_SETVBUF
  333.         setvbuf(stdin,  (char *)NULL, _IONBF, BUFSIZ);
  334.         setvbuf(stdout, (char *)NULL, _IONBF, BUFSIZ);
  335.         setvbuf(stderr, (char *)NULL, _IONBF, BUFSIZ);
  336. #else /* !HAVE_SETVBUF */
  337.         setbuf(stdin,  (char *)NULL);
  338.         setbuf(stdout, (char *)NULL);
  339.         setbuf(stderr, (char *)NULL);
  340. #endif /* !HAVE_SETVBUF */
  341. #else /* MPW */
  342.         /* On MPW (3.2) unbuffered seems to hang */
  343.         setvbuf(stdin,  (char *)NULL, _IOLBF, BUFSIZ);
  344.         setvbuf(stdout, (char *)NULL, _IOLBF, BUFSIZ);
  345.         setvbuf(stderr, (char *)NULL, _IOLBF, BUFSIZ);
  346. #endif /* MPW */
  347.     }
  348.     else if (Py_InteractiveFlag) {
  349. #ifdef MS_WINDOWS
  350.         /* Doesn't have to have line-buffered -- use unbuffered */
  351.         /* Any set[v]buf(stdin, ...) screws up Tkinter :-( */
  352.         setvbuf(stdout, (char *)NULL, _IONBF, BUFSIZ);
  353. #else /* !MS_WINDOWS */
  354. #ifdef HAVE_SETVBUF
  355.         setvbuf(stdin,  (char *)NULL, _IOLBF, BUFSIZ);
  356.         setvbuf(stdout, (char *)NULL, _IOLBF, BUFSIZ);
  357. #endif /* HAVE_SETVBUF */
  358. #endif /* !MS_WINDOWS */
  359.         /* Leave stderr alone - it should be unbuffered anyway. */
  360.       }
  361.  
  362.     Py_SetProgramName(argv[0]);
  363.     Py_Initialize();
  364.  
  365. #ifdef AMITCP
  366.     /** Sadly, this function cannot be called as a SAS/C standard **/
  367.     /** constructor function. It needs to have the interpreter **/
  368.     /** initialised because it uses the Python Error functions... **/
  369.     (void)_install_AmiTCP_callback();
  370. #endif
  371.  
  372.     if (Py_VerboseFlag ||
  373.         (command == NULL && filename == NULL && stdin_is_interactive))
  374.         fprintf(stderr, "Python %s on %s\n%s\n",
  375.             Py_GetVersion(), Py_GetPlatform(), Py_GetCopyright());
  376.     
  377.     
  378.     if (command != NULL) {
  379.         /* Backup optind and force sys.argv[0] = '-c' */
  380.         optind--;
  381.         argv[optind] = "-c";
  382.     }
  383.  
  384.     PySys_SetArgv(argc-optind, argv+optind);
  385.  
  386.     if ((inspect || (command == NULL && filename == NULL)) &&
  387.         isatty(fileno(stdin))) {
  388.         PyObject *v;
  389.         v = PyImport_ImportModule("readline");
  390.         if (v == NULL)
  391.             PyErr_Clear();
  392.         else
  393.             Py_DECREF(v);
  394.     }
  395.  
  396.     if (command) {
  397.         sts = PyRun_SimpleString(command) != 0;
  398.         free(command);
  399.     }
  400.     else {
  401.         if (filename == NULL && stdin_is_interactive) {
  402.             char *startup = getenv("PYTHONSTARTUP");
  403.             if (startup != NULL && startup[0] != '\0') {
  404.                 FILE *fp = fopen(startup, "r");
  405.                 if (fp != NULL) {
  406.                     (void) PyRun_SimpleFile(fp, startup);
  407.                     PyErr_Clear();
  408.                     fclose(fp);
  409.                 }
  410.             }
  411.         }
  412.         sts = PyRun_AnyFile(
  413.             fp,
  414.             filename == NULL ? "<stdin>" : filename) != 0;
  415.         if (filename != NULL)
  416.             fclose(fp);
  417.     }
  418.  
  419.     if (inspect && stdin_is_interactive &&
  420.         (filename != NULL || command != NULL))
  421.         sts = PyRun_AnyFile(stdin, "<stdin>") != 0;
  422.  
  423.     Py_Finalize();
  424.     return sts;
  425. }
  426.  
  427.  
  428. /* Make the *original* argc/argv available to other modules.
  429.    This is rare, but it is needed by the secureware extension. */
  430.  
  431. void
  432. Py_GetArgcArgv(argc, argv)
  433.     int *argc;
  434.     char ***argv;
  435. {
  436.     *argc = orig_argc;
  437.     *argv = orig_argv;
  438. }
  439.